package com.juzishuke.margin.framework.web;

import static com.juzishuke.margin.framework.web.WebConstants.DISCOVERY_KEY_VERSION;
import static com.juzishuke.margin.framework.web.WebConstants.WEB_ROUTE_KEY_VERSION;

import com.juzishuke.margin.framework.AppContext;
import java.io.IOException;
import java.util.Arrays;
import java.util.Optional;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * @author : libo@juzishuke.com
 * @Title :
 * @Description :
 * @date : 2024/4/9 16:58
 * @since :1.0
 */
@Slf4j
public class VersionFilter extends OncePerRequestFilter {

    /**
     * 优先级 param > header > cookie
     */
    @Override
    protected void doFilterInternal(final HttpServletRequest httpServletRequest,
            final HttpServletResponse httpServletResponse, final FilterChain filterChain)
            throws ServletException, IOException {
        String paramVersion = httpServletRequest.getParameter(WEB_ROUTE_KEY_VERSION);
        if (StringUtils.isNotEmpty(paramVersion)) {
            AppContext.setThreadLocal(DISCOVERY_KEY_VERSION, paramVersion);
        }
        Optional<Cookie> cookie = Arrays.stream(httpServletRequest.getCookies())
                .filter(e -> StringUtils.equalsIgnoreCase(WEB_ROUTE_KEY_VERSION, e.getName()))
                .findFirst();
        if (cookie.isPresent()) {
            String cookieVersion = cookie.get().getValue();
            if (StringUtils.isNotEmpty(cookieVersion)) {
                AppContext.setThreadLocal(DISCOVERY_KEY_VERSION, cookieVersion);
            }
        }
        String version = httpServletRequest.getHeader(WEB_ROUTE_KEY_VERSION);
        if (StringUtils.isNotEmpty(version)) {
            AppContext.setThreadLocal(DISCOVERY_KEY_VERSION, version);
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
